﻿using System;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using StockLib;
using StockLib.Quote;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using StockUtil;

namespace StockUI
{
    public partial class FormMain : FormAbstractParent
    {
        private bool _close = true;

        private bool _icon = false;

        private bool _connect = false;

        private int _reportMenuItemCount = 0;

        private static FormMain _instance = new FormMain();

        private FormKey _formKey = null;

        public static FormMain Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new FormMain();
                }

                return _instance;
            }
        }

        private FormMain()
        {
            InitializeComponent();

            this.Font = StockProfile.Fonts.DefaultFont;

            menuReportMy.Text = StockBlockGroupCustom.Instance.ZXGBlock.Name;
            menuReportMy.Tag = StockBlockGroupCustom.Instance.ZXGBlock.BlockId;

            lblSZZS.Tag = StockLib.StockMarket.SHSE + StockLib.StockConst.INDEX_SZZS;
            lblSZNCZ.Tag = StockLib.StockMarket.SZSE + StockLib.StockConst.INDEX_SZNCZ;
            lblSZNZXBZ.Tag = StockLib.StockMarket.SZSE + StockLib.StockConst.INDEX_SZNZXBZ;

            _reportMenuItemCount = menuReport.DropDownItems.Count;

            // 行情接收器状态变化时进行处理
            StockReceiver.Instance.StatusChanged += new ReceiverStatusEventHandler(Instance_StatusChanged);

            // 容器数据变化时进行处理
            StockContainer.Instance.DataChanged += new StockContainerDataEventHandler(Container_DataChanged);

            //订阅板块容器数据更改事件
            StockBlockGroupCustom.Instance.DataChanged += new StockBlockGroupDataEventHandler(StockBlockContainer_DataChanged);
        }

        // 行情接收器状态变化时，更新图标和菜单
        private void Instance_StatusChanged(object sender, ReceiverStatusEventArgs e)
        {
            cmdSysConnect.Enabled = !e.IsWorking;
            cmdSysDisconnect.Enabled = !cmdSysConnect.Enabled;
            picStatusConnect.Control.Image = e.IsWorking ? picStatusConnect.Control.InitialImage : picStatusConnect.Control.ErrorImage;
        }

        // 容器数据变化时，更新状态栏
        private void Container_DataChanged(object sender, EventArgs e)
        {
            if (StockContainer.Instance.ContainsKey(lblSZZS.Tag.ToString()))
            {
                ReportData reportSZZS = StockContainer.Instance[lblSZZS.Tag.ToString()].Report;
                lblSZZS.Text = string.Format("{0:F2}  {1:F2}  {2:F2}%", reportSZZS.New, reportSZZS.New - reportSZZS.Close, (reportSZZS.New - reportSZZS.Close) * 100 / reportSZZS.Close);
                lblSZZS.ForeColor = (reportSZZS.New < reportSZZS.Close) ? Color.DarkGreen : Color.Red;
            }

            if (StockContainer.Instance.ContainsKey(lblSZNCZ.Tag.ToString()))
            {
                ReportData reportSZNCZ = StockContainer.Instance[lblSZNCZ.Tag.ToString()].Report; lblSZNCZ.Text = string.Format("{0:F2}  {1:F2}  {2:F2}%", reportSZNCZ.New, reportSZNCZ.New - reportSZNCZ.Close, (reportSZNCZ.New - reportSZNCZ.Close) * 100 / reportSZNCZ.Close);
                lblSZNCZ.Text = string.Format("{0:F2}  {1:F2}  {2:F2}%", reportSZNCZ.New, reportSZNCZ.New - reportSZNCZ.Close, (reportSZNCZ.New - reportSZNCZ.Close) * 100 / reportSZNCZ.Close);
                lblSZNCZ.ForeColor = (reportSZNCZ.New < reportSZNCZ.Close) ? Color.DarkGreen : Color.Red;
            }

            if (StockContainer.Instance.ContainsKey(lblSZNZXBZ.Tag.ToString()))
            {
                ReportData reportSZNZXBZ = StockContainer.Instance[lblSZNZXBZ.Tag.ToString()].Report;
                lblSZNZXBZ.Text = string.Format("{0:F2}  {1:F2}  {2:F2}%", reportSZNZXBZ.New, reportSZNZXBZ.New - reportSZNZXBZ.Close, (reportSZNZXBZ.New - reportSZNZXBZ.Close) * 100 / reportSZNZXBZ.Close);
                lblSZNZXBZ.ForeColor = (reportSZNZXBZ.New < reportSZNZXBZ.Close) ? Color.DarkGreen : Color.Red;
            }
        }

        //板块容器数据更改时，更新页签显示
        private void StockBlockContainer_DataChanged(object sender, EventArgs e)
        {
            CreateGroupMenu(StockBlockGroupCustom.BLOCK_GROUP_NAME);
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.Style &= (~0XC00000); // | 0X80000 | 0X40000 | 0x20000 | 0x10000 | 0x800000;

                return cp;
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            //注册快捷键
            //RegisterAllHotKeys();

            //创建板块列表菜单
            CreateAllGroupMenu();

            //窗口最大边框为工作区
            MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
            WindowState = FormWindowState.Maximized;

            // 容器数据载入发生变化
            Container_DataChanged(StockContainer.Instance, new EventArgs());

            //创建行情窗口
            FindFormChild("Report");

            //自动连接服务器
            if (_connect)
            {
                ConnectServer(true);
            }
        }

        private void FormMain_Resize(object sender, EventArgs e)
        {
            //最小化到托盘区
            if (WindowState == FormWindowState.Minimized)
            {
                Visible = !_icon;
                notifyMain.Visible = _icon;
            }
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //如果开关为打开，点击关闭最小化到托盘
            if (!_close)
            {
                WindowState = FormWindowState.Minimized;
                e.Cancel = true;
                return;
            }

            //注销快捷键
            //UnregisterAllHotKeys();

            //断开数据连接
            ConnectServer(false);
        }

        private void FormMain_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Regex.IsMatch(e.KeyChar.ToString(), "^[0-9A-Za-z?]$"))
            {
                if (_formKey == null)
                {
                    _formKey = new FormKey();
                    _formKey.Selected += new FormKeySelectedEventHandler(FormKey_Selected);
                }

                if (ActiveFormChild != null)
                {
                    _formKey.Location = ActiveFormChild.PointToScreen(ActiveFormChild.Location);
                    _formKey.Top += ActiveFormChild.Height - _formKey.Height;
                    _formKey.Left += ActiveFormChild.Width - _formKey.Width;
                    _formKey.InitChars = e.KeyChar.ToString();
                    _formKey.ShowDialog(this);
                }
            }
        }

        private void FormKey_Selected(object sender, FormKeySelectedEventArgs e)
        {
            SendMessage(FormMain.Instance.FindFormChild("Graph"), new FormNotifyMessage("Graph.Show", e.Stock));
        }

        //点击托盘区图标，恢复窗口
        private void notifyMain_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                cmdNotifyRestore_Click(sender, e);
            }
        }

        //点击系统->退出菜单
        private void cmdSysExit_Click(object sender, EventArgs e)
        {
            _close = true;
            Close();
        }

        //点击系统->连接服务器或者系统->断开服务器菜单
        private void cmdSysConnect_Click(object sender, EventArgs e)
        {
            ConnectServer(cmdSysConnect.Enabled);
        }

        //点击帮助->关于菜单
        private void cmdHelpAbout_Click(object sender, EventArgs e)
        {
            new DialogAbout().ShowDialog();
        }

        //点击板块菜单
        private void cmdReportClass_Click(object sender, EventArgs e)
        {
            if (!(sender is ToolStripMenuItem))
                return;

            string blockId = Convert.ToString((sender as ToolStripMenuItem).Tag);
            string blockLabel = (sender as ToolStripMenuItem).Text;
            if (!string.IsNullOrEmpty(blockId))
            {
                CheckBlockMenu(blockId);

                SendMessage(FindFormChild("Report"), new FormNotifyMessage("Report.Show", blockLabel, blockId));
            }
        }

        //双击状态栏连接服务器图标
        private void picStatusConnect_Click(object sender, EventArgs e)
        {
            cmdSysConnect_Click(sender, e);
        }

        //点击托盘区退出菜单
        private void cmdNotifyExit_Click(object sender, EventArgs e)
        {
            cmdSysExit_Click(sender, e);
        }

        //点击托盘区显示主窗口菜单
        private void cmdNotifyRestore_Click(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                Show();
                WindowState = FormWindowState.Maximized;
                notifyMain.Visible = false;
            }
        }

        private void CheckBlockMenu(string blockId)
        {
            foreach (ToolStripItem mi in menuReport.DropDownItems)
            {
                if (!(mi is ToolStripMenuItem))
                    continue;

                string blockIdItem = Convert.ToString(mi.Tag);
                if (Regex.IsMatch(blockIdItem, @"^(.+)\.(.+)$"))
                {
                    (mi as ToolStripMenuItem).Checked = (blockId == blockIdItem);
                }
                if (Regex.IsMatch(blockIdItem, @"^(.+)\.$"))
                {
                    foreach (ToolStripItem mi2 in (mi as ToolStripMenuItem).DropDownItems)
                    {
                        if (!(mi2 is ToolStripMenuItem))
                            continue;

                        string blockIdItem2 = Convert.ToString(mi2.Tag);
                        (mi2 as ToolStripMenuItem).Checked = (blockId == blockIdItem2);
                    }
                }
            }
        }

        private void CreateAllGroupMenu()
        {
            CreateGroupMenu(StockBlockGroupClass.BLOCK_GROUP_NAME);
            foreach (string groupName in StockBlockGroupRegular.Instance.Groups)
            {
                CreateGroupMenu(groupName);
            }
            CreateGroupMenu(StockBlockGroupCustom.BLOCK_GROUP_NAME);
        }

        private void CreateGroupMenu(string groupName)
        {
            string groupId = groupName + ".";

            ToolStripMenuItem item = null;
            foreach (ToolStripItem tsi in menuReport.DropDownItems)
            {
                if (tsi is ToolStripMenuItem)
                {
                    string groupIdItem = Convert.ToString(tsi.Tag);
                    if (groupId == groupIdItem)
                    {
                        item = tsi as ToolStripMenuItem;
                        break;
                    }
                }
            }
            bool exist = (item != null);
            if (!exist)
            {
                item = new ToolStripMenuItem(groupName);
                item.Tag = groupId;
                menuReport.DropDownItems.Insert(menuReport.DropDownItems.Count - _reportMenuItemCount, item);
            }

            // 板块菜单需要重建，其他预定义菜单只有初始化的时候需要创建
            if (!exist || groupId == StockBlockGroupCustom.BLOCK_GROUP_ID)
            {
                IEnumerable blockList = null;
                switch (groupId)
                {
                    case StockBlockGroupClass.BLOCK_GROUP_ID:
                        blockList = StockBlockGroupClass.Instance.Values;
                        break;

                    case StockBlockGroupCustom.BLOCK_GROUP_ID:
                        blockList = StockBlockGroupCustom.Instance.Values.Where(d => (d.BlockId != StockBlockGroupCustom.Instance.ZXGBlock.BlockId));
                        break;

                    default:
                        blockList = StockBlockGroupRegular.Instance.Values.Where(d => d.GroupId == groupId);
                        break;
                }
                if (blockList == null)
                    return;

                item.DropDownItems.Clear();
                foreach (StockBlock block in blockList)
                {
                    ToolStripMenuItem tsmi = new ToolStripMenuItem(block.Name);
                    tsmi.Tag = block.BlockId;
                    tsmi.Click += cmdReportClass_Click;
                    item.DropDownItems.Add(tsmi);
                }
            }
        }

        //连接服务器
        private void ConnectServer(bool connect)
        {
            if (connect)
                StockReceiver.Instance.StartWorking();
            else
                StockReceiver.Instance.StopWorking();
        }

        private void cmdToolFormula_Click(object sender, EventArgs e)
        {
            //SendKeys.Send("^f");
        }

        private void cmdToolAlarm_Click(object sender, EventArgs e)
        {
            //SendKeys.Send("^j");
        }

        private void cmdToolStockSelector_Click(object sender, EventArgs e)
        {
            //SendKeys.Send("^s");
        }

        private void cmdOptionSys_Click(object sender, EventArgs e)
        {
            //SendKeys.Send("^d");
        }

        private void cmdOptionBlock_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^b");
        }

        private void cmdOptionTab_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^t");
        }

        private void menuReportMy_Click(object sender, EventArgs e)
        {
            SendKeys.Send("{F6}");
        }

        private void lblSZZS_DoubleClick(object sender, EventArgs e)
        {            
            string codeKey = Convert.ToString((sender as ToolStripItem).Tag);
            if (StockContainer.Instance.ContainsKey(codeKey))
            {
                Stock stock = StockContainer.Instance[codeKey];
                SendMessage(FindFormChild("Graph"), new FormNotifyMessage("Graph.Show", stock));
            }
        }

        private void cmdBlockSetup_Click(object sender, EventArgs e)
        {
            SendKeys.Send("^b");
        }
    }
}
